package com.hotelManager.www.service;

import com.hotelManager.www.dao.OrderDao;
import com.hotelManager.www.dao.RoomDao;
import com.hotelManager.www.dao.RoomTypeDao;
import com.hotelManager.www.dao.ShopDao;
import com.hotelManager.www.dao.UserDao;
import com.hotelManager.www.po.Order;
import com.hotelManager.www.po.Room;
import com.hotelManager.www.po.RoomType;
import com.hotelManager.www.po.Shop;
import com.hotelManager.www.po.User;
import com.hotelManager.www.util.JDBCUtils;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

public class OrderService {
    private static OrderDao orderDao;
    private static RoomDao roomDao;
    private static ShopDao shopDao;
    private static UserDao userDao;
    private static RoomTypeDao roomTypeDao;

    static {
        try {
            orderDao = new OrderDao();
            roomDao = new RoomDao();
            shopDao = new ShopDao();
            userDao = new UserDao();
            roomTypeDao = new RoomTypeDao();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 创建订单
    public static Order createOrder(Integer userId, Integer shopId, String roomCode, Integer days) throws Exception {
        Connection conn = null;
        try {
            conn = JDBCUtils.getConnection();
            conn.setAutoCommit(false);

            // 检查店铺状态
            Shop shop = shopDao.findById(shopId);
            if (shop == null) {
                throw new RuntimeException("店铺不存在");
            }
            if (!"open".equals(shop.getStatus())) {
                throw new RuntimeException("店铺已关闭，无法预订");
            }

            // 通过房间号查找房间
            Room room = roomDao.findByRoomCode(conn, roomCode);
            if (room == null) {
                throw new Exception("房间不存在");
            }
            
            // 检查房间状态是否为可用
            if (!"available".equals(room.getStatus())) {
                throw new Exception("房间状态不可用");
            }

            // 检查房型库存
            RoomType roomType = roomTypeDao.findById(room.getRoomTypeId());
            if (roomType == null) {
                throw new Exception("房型不存在");
            }
            
            if (roomType.getStock() <= 0) {
                throw new Exception("房型库存不足");
            }

            // 1. 获取店铺信息
            if (shopId == null) {
                shop = shopDao.findByUserId(userId);
                if (shop == null) {
                    throw new Exception("未找到用户关联的店铺");
                }
                shopId = shop.getId();
            } else {
                shop = shopDao.findById(shopId);
                if (shop == null) {
                    throw new Exception("店铺不存在");
                }
            }

            // 3. 创建订单
            Order order = new Order();
            order.setUserId(userId);
            order.setShopId(shopId);
            order.setRoomId(room.getId());
            order.setStatus("pending");
            order.setTotalAmount(roomType.getPrice().multiply(new BigDecimal(days)));
            order.setCreateTime(LocalDateTime.now());
            order.setShopName(shop.getShopname());
            order.setUniRoomCode(roomCode);

            // 4. 保存订单
            orderDao.save(order);

            // 5. 更新房间状态为已预订
            if (!roomDao.updateStatusByRoomCode(conn, roomCode, "booked")) {
                throw new Exception("更新房间状态失败");
            }

            // 6. 更新房间库存
            roomTypeDao.updateStock(room.getRoomTypeId(), -1);

            // 7. 更新酒店销量
            shopDao.updateSalesVolume(shopId, 1);

            conn.commit();
            return order;
        } catch (Exception e) {
            if (conn != null) {
                try {
                    conn.rollback();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
            throw e;
        } finally {
            if (conn != null) {
                try {
                    conn.setAutoCommit(true);
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 保存订单
    public void save(Order order) throws Exception {
        String sql = "INSERT INTO orders (user_id, shop_id, room_id, total_amount, status, create_time, shop_name, uni_room_code) " +
                     "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
        try (Connection conn = JDBCUtils.getConnection();
             PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
            ps.setInt(1, order.getUserId());
            ps.setInt(2, order.getShopId());
            ps.setInt(3, order.getRoomId());
            ps.setBigDecimal(4, order.getTotalAmount());
            ps.setString(5, order.getStatus());
            ps.setTimestamp(6, Timestamp.valueOf(order.getCreateTime()));
            ps.setString(7, order.getShopName());
            ps.setString(8, order.getUniRoomCode());

            int rowsAffected = ps.executeUpdate();

            // 获取生成的订单 ID
            if (rowsAffected > 0) {
                try (ResultSet rs = ps.getGeneratedKeys()) {
                    if (rs.next()) {
                        order.setId(rs.getInt(1)); // 设置订单 ID
                    }
                }
            } else {
                throw new SQLException("保存订单失败，未插入任何行");
            }
        }
    }

    // 取消订单
    public boolean cancelOrder(Integer userId, Integer orderId) throws Exception {
        Connection conn = null;
        try {
            conn = JDBCUtils.getConnection();
            conn.setAutoCommit(false);

            // 1. 获取订单信息
            Order order = orderDao.findById(orderId);
            if (order == null) {
                throw new Exception("订单不存在");
            }

            // 2. 检查订单状态
            if (!"pending".equals(order.getStatus()) && !"confirmed".equals(order.getStatus())) {
                throw new Exception("只有待支付或已确认的订单可以取消");
            }

            // 3. 如果订单已支付，返还用户余额
            if ("confirmed".equals(order.getStatus())) {
                userDao.updateBalance(userId, order.getTotalAmount());
            }

            // 4. 更新订单状态
            order.setStatus("cancelled");
            orderDao.update(order);

            // 5. 恢复房间状态为可用
            if (!roomDao.updateStatusByRoomCode(conn, order.getUniRoomCode(), "available")) {
                throw new Exception("恢复房间状态失败");
            }

            // 6. 恢复房间库存
            roomTypeDao.updateStock(order.getRoomId(), 1);

            // 7. 减少酒店销量
            shopDao.updateSalesVolume(order.getShopId(), -1);

            conn.commit();
            return true;
        } catch (Exception e) {
            if (conn != null) {
                conn.rollback();
            }
            throw e;
        } finally {
            if (conn != null) {
                conn.setAutoCommit(true);
                conn.close();
            }
        }
    }

    // 查询用户的所有订单
    public static List<Order> getOrdersByUserId(Integer userId) throws Exception {
        return orderDao.findByUserId(userId);
    }

    // 查询订单详情
    public static Order getOrderById(Integer orderId) throws Exception {
        return orderDao.findById(orderId);
    }

    // 更新订单状态
    public void updateOrderStatus(Integer orderId, String status, Integer userId) throws Exception {
        Connection conn = null;
        try {
            conn = JDBCUtils.getConnection();
            conn.setAutoCommit(false);

            // 1. 获取订单信息
            Order order = orderDao.findById(orderId);
            if (order == null) {
                throw new Exception("订单不存在");
            }

            // 2. 获取用户信息
            User user = userDao.findById(userId);
            if (user == null) {
                throw new Exception("用户不存在");
            }

            // 3. 检查余额是否足够
            if (user.getBalance().compareTo(order.getTotalAmount()) < 0) {
                throw new Exception("余额不足，请先充值");
            }

            // 4. 扣除用户余额
            userDao.updateBalance(userId, order.getTotalAmount().negate());

            // 5. 更新订单状态
            order.setStatus(status);
            orderDao.update(order);

            conn.commit();
        } catch (Exception e) {
            if (conn != null) {
                conn.rollback();
            }
            throw e;
        } finally {
            if (conn != null) {
                conn.setAutoCommit(true);
                conn.close();
            }
        }
    }

    // 完成订单（核销）
    public boolean completeOrder(Integer orderId, Integer userId) {
        Connection conn = null;
        PreparedStatement ps = null;
        
        try {
            conn = JDBCUtils.getConnection();
            conn.setAutoCommit(false);  // 开启事务
            
            // 1. 查询订单是否存在且状态为confirmed
            String checkSql = "SELECT status, shop_id, total_amount FROM orders WHERE id = ?";
            ps = conn.prepareStatement(checkSql);
            ps.setInt(1, orderId);
            ResultSet rs = ps.executeQuery();
            
            if (!rs.next()) {
                throw new RuntimeException("订单不存在，ID: " + orderId);
            }
            
            String status = rs.getString("status");
            Integer shopId = rs.getInt("shop_id");
            BigDecimal totalAmount = rs.getBigDecimal("total_amount");
            
            if (!"confirmed".equals(status)) {
                throw new RuntimeException("订单状态不是confirmed，无法完成订单");
            }
            
            // 检查用户是否有权限完成订单
            Shop shop = shopDao.findByUserId(userId);
            if (shop == null || !shop.getId().equals(shopId)) {
                throw new RuntimeException("您没有权限完成此订单");
            }
            
            // 检查店铺状态
            if (!"open".equals(shop.getStatus())) {
                throw new RuntimeException("店铺已关闭，无法完成订单");
            }
            
            // 2. 更新订单状态为completed
            String updateSql = "UPDATE orders SET status = 'completed' WHERE id = ?";
            ps = conn.prepareStatement(updateSql);
            ps.setInt(1, orderId);
            
            int result = ps.executeUpdate();
            
            if (result > 0) {
                // 3. 更新店铺营业额
                if (!shopDao.updateRevenue(conn, shopId, totalAmount)) {
                    throw new RuntimeException("更新店铺营业额失败");
                }
                
                conn.commit();
                return true;
            } else {
                conn.rollback();
                return false;
            }
            
        } catch (Exception e) {
            try {
                if (conn != null) {
                    conn.rollback();
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            throw new RuntimeException("完成订单失败：" + e.getMessage());
        } finally {
            try {
                if (ps != null) ps.close();
                if (conn != null) conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    // 根据用户ID获取店铺ID
    public static Integer getShopIdByUserId(Integer userId) throws Exception {
        Connection conn = null;
        try {
            conn = JDBCUtils.getConnection();
            Shop shop = shopDao.findByUserId(userId);
            if (shop != null) {
                return shop.getId();
            }
            return null;
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 申请退房
    public boolean requestRefund(Integer userId, Integer orderId) throws Exception {
        Connection conn = null;
        try {
            conn = JDBCUtils.getConnection();
            conn.setAutoCommit(false);

            // 1. 获取订单信息
            Order order = orderDao.findById(orderId);
            if (order == null) {
                throw new Exception("订单不存在");
            }

            // 2. 检查订单是否属于该用户
            if (!order.getUserId().equals(userId)) {
                throw new Exception("无权操作此订单");
            }

            // 3. 检查订单状态是否为已确认
            if (!"confirmed".equals(order.getStatus())) {
                throw new Exception("只有已确认的订单可以申请退房");
            }

            // 4. 更新订单状态为退房申请中
            order.setStatus("refund");
            orderDao.update(order);

            conn.commit();
            return true;
        } catch (Exception e) {
            if (conn != null) {
                conn.rollback();
            }
            throw e;
        } finally {
            if (conn != null) {
                conn.setAutoCommit(true);
                conn.close();
            }
        }
    }

    // 处理退房申请（商家审核）
    public boolean processRefundRequest(Integer orderId, Integer shopId, boolean approved) throws Exception {
        Connection conn = null;
        try {
            conn = JDBCUtils.getConnection();
            conn.setAutoCommit(false);

            // 1. 获取订单信息
            Order order = orderDao.findById(orderId);
            if (order == null) {
                throw new Exception("订单不存在");
            }

            // 2. 检查订单是否属于该商家
            if (!order.getShopId().equals(shopId)) {
                throw new Exception("无权操作此订单");
            }

            // 3. 检查订单状态是否为退房申请中
            if (!"refund".equals(order.getStatus())) {
                throw new Exception("该订单不是退房申请状态");
            }

            if (approved) {
                // 4. 如果同意退房，更新订单状态为已取消
                order.setStatus("cancelled");
                orderDao.update(order);

                // 5. 返还用户余额
                userDao.updateBalance(order.getUserId(), order.getTotalAmount());

                // 6. 恢复房间状态为可用
                if (!roomDao.updateStatusByRoomCode(conn, order.getUniRoomCode(), "available")) {
                    throw new Exception("恢复房间状态失败");
                }

                // 7. 恢复房间库存
                roomTypeDao.updateStock(order.getRoomId(), 1);

                // 8. 减少酒店销量
                shopDao.updateSalesVolume(order.getShopId(), -1);
            } else {
                // 9. 如果拒绝退房，更新订单状态为已确认
                order.setStatus("confirmed");
                orderDao.update(order);
            }

            conn.commit();
            return true;
        } catch (Exception e) {
            if (conn != null) {
                conn.rollback();
            }
            throw e;
        } finally {
            if (conn != null) {
                conn.setAutoCommit(true);
                conn.close();
            }
        }
    }

    // 获取商家的退房申请列表
    public List<Order> getRefundRequestsByShopId(Integer shopId) throws Exception {
        String sql = "SELECT o.*,  u.username as user_name " +
                    "FROM orders o " +
                    "JOIN room r ON o.room_id = r.id " +
                    "JOIN users u ON o.user_id = u.id " +
                    "WHERE o.shop_id = ? AND o.status = 'refund'";
        
        List<Order> orders = new ArrayList<>();
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        
        try {
            conn = JDBCUtils.getConnection();
            ps = conn.prepareStatement(sql);
            ps.setInt(1, shopId);
            rs = ps.executeQuery();
            
            while (rs.next()) {
                Order order = new Order();
                order.setId(rs.getInt("id"));
                order.setUserId(rs.getInt("user_id"));
                order.setShopId(rs.getInt("shop_id"));
                order.setRoomId(rs.getInt("room_id"));
                order.setTotalAmount(rs.getBigDecimal("total_amount"));
                order.setStatus(rs.getString("status"));
                order.setCreateTime(rs.getTimestamp("create_time").toLocalDateTime());
                order.setShopName(rs.getString("shop_name"));
                order.setUniRoomCode(rs.getString("uni_room_code"));
                orders.add(order);
            }
        } finally {
            if (rs != null) rs.close();
            if (ps != null) ps.close();
            if (conn != null) conn.close();
        }
        
        return orders;
    }

    /**
     * 处理被禁商家的订单退款
     * @param shopId 被禁商家ID
     * @return 是否处理成功
     */
    public boolean refundOrdersForBannedShop(Integer shopId) {
        Connection conn = null;
        try {
            conn = JDBCUtils.getConnection();
            conn.setAutoCommit(false);
            
            // 1. 获取该商家所有已确认的订单
            List<Order> confirmedOrders = orderDao.findByShopIdAndStatus(shopId, "confirmed");
            
            // 2. 处理每个订单的退款
            for (Order order : confirmedOrders) {
                // 更新订单状态为已取消
                order.setStatus("cancelled");
                boolean updateSuccess = orderDao.updateResult(order); // 使用更新后的方法

                if (!updateSuccess) {
                    conn.rollback();
                    return false;
                }

                // 退款给用户
                User user = userDao.findById(order.getUserId());
                if (user != null) {
                    user.setBalance(user.getBalance().add(order.getTotalAmount()));
                    boolean refundSuccess = userDao.update(conn, user);

                    if (!refundSuccess) {
                        conn.rollback();
                        return false;
                    }
                }
            }
            
            conn.commit();
            return true;
        } catch (Exception e) {
            try {
                if (conn != null) {
                    conn.rollback();
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (conn != null) {
                    conn.setAutoCommit(true);
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    // 检查是否可以创建订单
    public boolean canCreateOrder(Integer shopId) {
        Connection conn = null;
        try {
            conn = JDBCUtils.getConnection();
            Shop shop = shopDao.findById(shopId);
            if (shop == null) {
                throw new RuntimeException("店铺不存在");
            }
            String status = shop.getStatus();
            return "open".equals(status);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            JDBCUtils.closeConnection(conn);
        }
    }

    // 根据店铺ID获取订单列表，过滤条件：audit_status为pending或status为banned的商家无法获取订单
    public List<Order> getOrdersByShopId(Integer shopId) throws Exception {
        Connection conn = null;
        try {
            conn = JDBCUtils.getConnection();

            // 检查商家状态
            Shop shop = shopDao.findById(shopId);
            if (shop == null) {
                throw new IllegalArgumentException("店铺不存在");
            }
            if ("pending".equals(shop.getAuditStatus()) || "banned".equals(shop.getStatus())) {
                throw new IllegalStateException("商家审核中或已被禁用，无法获取订单");
            }


            // 获取店铺的user_id
            Integer userId = shop.getUserId();

            // 获取订单列表
            return orderDao.findByUserId(userId);
        } finally {
            if (conn != null) {
                conn.close();
            }
        }
    }
}
